import { Injectable } from '@angular/core';

@Injectable({
    providedIn: 'root'
})
export class IndexDbHelpService {
    
    constructor() { }

    /**
     * 创建数据库(包含实体)
     * @param DBname 数据库名称(必填)
     * @param Version 数据库版本号(必填)
     * @param StorageName 数据实体名称(必填)
     * @param KeyName 主键(必填)
     * @param BusinessData 数据实体集合(必填)
     */
    createIndexDB(DBname, Version, StorageName, KeyName, BusinessData) {
        let that = this;
        if (!window.indexedDB) {
            alert("您的浏览器不支持IndexedDB缓存数据库,请使用IE1或谷歌23以上版本的浏览器。");
            return;
        }
        let openRequest = window.indexedDB.open(DBname, Version);
        openRequest.onerror = function (e) {
            console.log("创建失败：", this.error.message);
        };
        openRequest.onsuccess = function (e) {
            let db = this.result;
            // //界面Load时不会触发页面关闭事件,未删除缓存数据库,所以此处重新获取数据库数据覆盖缓存数据
            // if (BusinessData != null && BusinessData.length > 0) {
            //     var trans = db.transaction(StorageName, "readwrite");
            //     var store = trans.objectStore(StorageName);
            //     for (var i = 0; i < BusinessData.length; i++) {
            //         store.put(BusinessData[i]);
            //     }
            //     console.log("初始化更新缓存成功");
            // }
        };
        openRequest.onupgradeneeded = function (e) {
            let db = this.result;
            //创建数据,相当于数据库结构修改,需要在onupgradeneeded中实现 
            that.createObjectStore(StorageName, KeyName, BusinessData, db);
            console.log("创建缓存成功");
        }
    };

    /**
     * 创建数据仓库
     * @param StorageName 数据实体名称(必填)
     * @param KeyName >主键(必填)
     * @param BusinessData 数据实体集合(必填)
     * @param db 数据库实例
     */
    createObjectStore(StorageName, KeyName, BusinessData, db) {
        let objectStore = db.createObjectStore(StorageName, { keyPath: KeyName });
        if (BusinessData != null && BusinessData.length) {
            for (let i = 0; i < BusinessData.length; i++) {
                objectStore.add(BusinessData[i]);
            }
        }
    };

    /**
     * 删除缓存数据库-异步
     * @param DBname 数据库名称(必填)
     */
    deleteDatabase(DBname) {
        return new Promise<any>((resolve, reject) => {
            let deleteDbRequest = window.indexedDB.deleteDatabase(DBname);
            deleteDbRequest.onsuccess = function (event) {
                console.log("删除缓存数据库成功");
                resolve(true);
            };
            deleteDbRequest.onerror = function (event) {
                console.log("删除缓存数据库失败");
                return reject(false);
            };
        });
    };

    /**
     * 关闭数据库-异步
     * @param DBname 数据库名称(必填)
     * @param Version 数据库版本(必填)
     */
    closeDB(DBname, Version) {
        return new Promise<any>((resolve, reject) => {
            let openRequest = window.indexedDB.open(DBname, Version);
            openRequest.onerror = function (e) {
                console.log("关闭数据库时打开数据库失败", this.error.message);
                return reject(false);
            };
            openRequest.onsuccess = function (e) {
                let db = this.result;
                db.close();
                console.log("关闭缓存成功");
                resolve(true);
            }
        });
    }

    /**
     * 添加数据-异步
     * @param StorageName 数据仓库名称(必填)
     * @param Entity 数据实体(必填)
     */
    addEntity(DbName, Version, StorageName, Entity) {
        return new Promise<any>((resolve, reject) => {
            let openRequest = window.indexedDB.open(DbName, Version);
            openRequest.onerror = function (e) {
                console.log("打开数据库失败", this.error.message);
                return reject(false);
            };
            openRequest.onsuccess = function (e) {
                let db = this.result;
                let st = db.transaction(StorageName, "readwrite");
                let store = st.objectStore(StorageName);
                let request = store.add(Entity);
                request.onerror = function (e) {
                    console.log("新增数据失败", this.error.message);
                    db.close();
                    return reject(false);
                }

                request.onsuccess = function (e) {
                    console.log("新增数据成功");
                    db.close();
                    resolve(true);
                }
            }
        });
    }

    /**
     * 删除数据-异步
     * @param StorageName 数据仓库名称(必填)
     * @param key 主键值(必填)
     */
    deleteEntityByKey(DbName, Version, StorageName, key) {
        return new Promise<any>((resolve, reject) => {
            let openRequest = window.indexedDB.open(DbName, Version);
            openRequest.onerror = function (e) {
                console.log("打开数据库失败" + this.error.message);
                return reject(false)
            };
            openRequest.onsuccess = function (e) {
                let db = this.result;
                let ts = db.transaction(StorageName, "readwrite");
                let req = ts.objectStore(StorageName).delete(key);
                req.onerror = function (e) {
                    console.log("删除指定缓存失败！" + this.error.message);
                    db.close();
                    return reject(false)
                }

                req.onsuccess = function (e) {
                    console.log("删除指定缓存成功！");
                    db.close();
                    resolve(true);
                }
            }
        });
    }

    /**
     * 更新数据-异步
     * @param StorageName 数据仓库名称(必填)
     * @param NewEntity 更新的数据实体(必填)
     */
    updateEntity(DbName, Version, StorageName, NewEntity): Promise<any> {
        return new Promise<any>((resolve, reject) => {
            let openRequest = window.indexedDB.open(DbName, Version);
            openRequest.onerror = function (e) {
                console.log("打开数据库失败" , this.error.message);
                return reject(false);
            };
            openRequest.onsuccess = function (e) {
                let db = this.result;
                let trans = db.transaction(StorageName, "readwrite");
                let store = trans.objectStore(StorageName);
                let req = store.put(NewEntity);
                req.onsuccess = () => {
                    db.close();
                    resolve(true);
                }
                req.onerror = () => {
                    db.close();
                    return reject(false);
                }
            }
        });
    }

    /**
     * 根据key获取数据-异步
     * @param DBname 数据库名称(必填)
     * @param Version 数据库版本(必填)
     * @param StorageName 数据仓库名称(必填)
     * @param Key 主键(必填)
     */
    getEntityForKey(DbName, Version, StorageName, Key) {
        return new Promise<any>((resolve, reject) => {
            let openRequest = window.indexedDB.open(DbName, Version);
            openRequest.onerror = function (e) {
                return reject("打开数据库失败" + this.error.message)
            };
            openRequest.onsuccess = function (e) {
                let db = this.result;
                let transaction = db.transaction(StorageName, "readwrite");
                let objectStore = transaction.objectStore(StorageName);
                let os = objectStore.get(Key);
                os.onerror = function (event) {
                    db.close();
                    return reject("获取失败！" + this.error.message)
                };
                os.onsuccess = function (event) {
                    db.close();
                    resolve(os.result);
                };
            }
        });
    }

    /**
     * 获取的数据实体集合-异步
     * @param DBname 数据库名称(必填)
     * @param Version 数据库版本(必填)
     * @param StorageName 数据仓库名称(必填)
     */
    getAllByStorage(DbName, Version, StorageName) {
        return new Promise<any>((resolve, reject) => {
            let openRequest = window.indexedDB.open(DbName, Version);
            openRequest.onerror = function (e) {
                return reject("打开数据库失败" + this.error.message)
            };
            openRequest.onsuccess = function (e) {
                let db = this.result;
                let trans = db.transaction(StorageName, "readwrite");;
                let store = trans.objectStore(StorageName);
                let EntityList = new Array();
                //创建游标遍历
                store.openCursor().onsuccess = function (event) {
                    var cursor = this.result;
                    if (cursor) {
                        EntityList.push(cursor.value);
                        cursor.continue();
                        db.close();

                        resolve(EntityList);
                    }
                    else {
                        db.close();
                        return reject("数据不存在" + this.error)
                    }
                };
                store.openCursor().onerror = function (event) {
                    db.close();
                    return reject("打开游标失败" + this.error)
                }
            };
        });
    }

}